package org.client.iot.ui.ble;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothProfile;
import android.content.pm.PackageManager;
import android.net.Network;
import android.view.View;

import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Observer;

import com.google.android.material.textfield.TextInputEditText;
import com.lucky.base.network.NetworkApi;
import com.lucky.base.network.observer.BaseObserver;
import com.lucky.utils.FastjsonUtils;
import com.lucky.utils.log.LogUtils;
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog;

import org.client.iot.R;
import org.client.iot.ble.WifiConnector;
import org.client.iot.ble.WifiScanner;
import org.client.iot.constant.GlobeConstant;
import org.client.iot.constant.GlobeDataManager;
import org.client.iot.databinding.ActivityBleConnectBinding;
import org.client.iot.domain.WifiInfo;
import org.client.iot.http.ApiService;
import org.client.iot.http.UpdateReqDto;
import org.client.iot.util.MMKVUtils;
import org.client.iot.util.PermissionManager;
import org.tzw.template.base.BaseActivity;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import cn.hutool.core.util.StrUtil;
import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.RequestBody;

public class BleConnectActivity extends BaseActivity<ActivityBleConnectBinding> {
    private WifiInfo bleDevice;
    private int projectId;
    private WifiConnector wifiConnector;
    private WifiScanner wifiScanner;
    private boolean retry = false;

    @Override
    protected void initData() {
        bleDevice = (WifiInfo) getIntent().getParcelableExtra("targetDev");
        projectId = getIntent().getIntExtra("projectId", 0);
        wifiConnector = new WifiConnector(this);
        wifiScanner = new WifiScanner(this);
    }

    @Override
    protected void initView() {
        mRoot.textViewDevName.setText(StrUtil.format("{}:{}", bleDevice.getSsid(), bleDevice.getFrequencyTag()));
        mRoot.textViewConnectText.setVisibility(View.GONE);
        mRoot.btnSet.setVisibility(View.GONE);
//        BleTemplate.getInstance().start(bleDevice);
    }

    @Override
    protected void initListener() {
        mRoot.bleConnectTabbar.imgBack.setOnClickListener(v -> {
            finish();
        });
        //添加设备
        mRoot.btnSet.setOnClickListener(v -> {
            if (!retry) {
                MaterialDialog materialDialog = new MaterialDialog.Builder(this)
                        .customView(R.layout.dialog_bind_dev, true)
                        .positiveText("确定")
                        .callback(new MaterialDialog.ButtonCallback() {
                            @Override
                            public void onPositive(MaterialDialog dialog) {
                                TextInputEditText devNameEdit = dialog.findViewById(R.id.textInput_dev_name);
                                TextInputEditText devTypeEdit = dialog.findViewById(R.id.textView_dev_type);
                                String devName = Objects.requireNonNull(devNameEdit.getText()).toString();
                                String devType = Objects.requireNonNull(devTypeEdit.getText()).toString();
                                if (devName.isEmpty() || devType.isEmpty()) {
                                    showToastShort("请输入设备名称或设备类型");
                                    return;
                                }
                                //serialNumber怎么取
                                addDev(devName, devType, "12345678", projectId);
                            }
                        })
                        .show();
            } else {
                connectWifi();
            }
        });
        GlobeDataManager.bluetoothProfileLiveData.observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer status) {
                if (status == GlobeConstant.WIFI_STATS.CONNECTING) {
                    mRoot.textViewConnectText.setVisibility(View.VISIBLE);
                    mRoot.btnSet.setVisibility(View.GONE);
                    retry = false;
                } else if (status == GlobeConstant.WIFI_STATS.TIME_OUT) {
                    mRoot.textViewConnectText.setVisibility(View.VISIBLE);
                    mRoot.textViewConnectText.setText(getString(R.string.wifi_retry_connect));
                    mRoot.btnSet.setText(View.VISIBLE);
                    mRoot.btnSet.setText(getString(R.string.wifi_retry_connect));
                    retry = true;
                } else if (status == GlobeConstant.WIFI_STATS.CONNECTED) {
                    showToastShort(getString(R.string.common_connect_ok));
                    mRoot.textViewConnectText.setVisibility(View.GONE);
                    mRoot.btnSet.setVisibility(View.VISIBLE);
                    retry = false;
                }
            }
        });
    }

    @Override
    protected void onStart() {
        PermissionManager.checkPermission(this, new PermissionManager.AcceptPermissionListener() {
            @Override
            public void onSuccess() {
                connectWifi();
            }

            @Override
            public void onFail() {
                showToastShort(getString(R.string.permission_error));
            }

            @Override
            public void onError(Throwable e) {
                showToastShort(StrUtil.format(getString(R.string.permission_error) + ":{}", e.getCause()));
            }
        }, Manifest.permission.ACCESS_FINE_LOCATION);
        super.onStart();
    }

    private void connectWifi() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
//        wifiScanner.connect();
        wifiConnector.connect(bleDevice.getSsid(), bleDevice.getPwd(), new WifiConnector.ConnectCallback() {
            @Override
            public void onConnecting() {
                GlobeDataManager.bluetoothProfileLiveData.postValue(GlobeConstant.WIFI_STATS.CONNECTING);
            }

            @Override
            public void onConnected(Network network) {
                GlobeDataManager.bluetoothProfileLiveData.postValue(GlobeConstant.WIFI_STATS.CONNECTED);
            }

            @Override
            public void onFailed(String reason) {
                GlobeDataManager.bluetoothProfileLiveData.postValue(GlobeConstant.WIFI_STATS.FAILED);
                runOnUiThread(() -> {
                    mRoot.textViewConnectText.setVisibility(View.VISIBLE);
                    mRoot.textViewConnectText.setText(reason);
                    mRoot.btnSet.setVisibility(View.VISIBLE);
                    mRoot.btnSet.setText(getString(R.string.wifi_retry_connect));
                    retry = true;
                });
            }

            @Override
            public void onTimeout() {
                GlobeDataManager.bluetoothProfileLiveData.postValue(GlobeConstant.WIFI_STATS.TIME_OUT);

            }
        });
    }

    //添加设备
    private void addDev(String deviceName, String productName, String serialNumber, int projectId) {
        String token = "Bearer " + MMKVUtils.getInstance().get("token", "");
        String params = FastjsonUtils.toJsonString(addDevParams(deviceName, productName, serialNumber, projectId, ""));
        Observable<UpdateReqDto> compose = NetworkApi.createService(ApiService.class, "")
                .addDevice(token, RequestBody.create(MediaType.parse("application/json"), params))
                .compose(NetworkApi.applySchedulers(new BaseObserver<UpdateReqDto>() {
                    @SuppressLint("CheckResult")
                    @Override
                    public void onSuccess(UpdateReqDto req) {
                        if (req == null) {
                            return;
                        }
                        runOnUiThread(() -> {
                            LogUtils.i("添加设备req==", req.toString());
                            showToastShort(req.getMsg());
                            finish();
                        });

                    }

                    @SuppressLint("CheckResult")
                    @Override
                    public void onFailure(Throwable e) {
                        runOnUiThread(() -> showToastLong(e.getMessage()));
                    }
                }));
    }

    private Map<String, Object> addDevParams(String deviceName, String productName, String serialNumber, int projectId, String remark) {
        Map<String, Object> params = new LinkedHashMap<>();
        params.put("deviceName", deviceName);
        params.put("productId", 181);
        params.put("productName", productName);
        params.put("serialNumber", serialNumber);
        params.put("projectId", projectId);
        params.put("remark", remark);
        return params;
    }

}